有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java多线程中的并发性

我在为ocjp 6考试进行模拟测试时,遇到了以下关于并发访问的问题:

public class Cruiser {
   private int a = 0;

    public void foo() {
        Runnable r = new LittleCruiser();
        new Thread(r).start();
        new Thread(r).start();
    }

    public static void main(String arg[]) {
        Cruiser c = new Cruiser();
        c.foo();
    }

public class LittleCruiser implements Runnable {
    public void run() {
            int current = 0;
            for (int i = 0; i < 4; i++) {
                current = a;
                System.out.print(current + ", ");
                a = current + 2;
            }
    }
}

可能的输出是什么

选项:

A)0,2,4,0,2,4,6,6

B)0,2,4,6,8,10,12,14

C)0,2,4,6,8,10,2,4

D)0,0,2,2,4,4,6,6,8,8,10,10,12,14,14

E)0,2,4,6,8,10,12,14,0,2,4,6,8,10,12,14

答案是A和B

我的疑问是,选项A怎么可能是一个可能的输出?我的意思是,如果第一个线程输入它的run方法,它会改变a的值,如果在第二个线程之间,它会得到a的改变值,那么为什么数字会重复呢? 请解释这个问题,提前谢谢


共 (2) 个答案

  1. # 1 楼答案

    下面是一个可能的场景,其中:

    • a列是a的值
    • 线程1是线程1的动作
    • 第一个电流是线程1的电流值
    • 线程2是线程2的动作
    • 第二个电流是螺纹2的电流值

    以下是步骤:

    a        Thread 1     current     Thread 2    current
                                 
    0        current = 0     0 
    0                                 current = 0    0
    0        current = a     0
    0                                 current = a    0
    0        print curr      0                                // Prints 0
    2        a = current+2   0
    2        current = a     2
    2        print current   2                                // Prints 0, 2
    4        a = current+2   2
    4        current = a     4
    4        print current   4                                // Prints 0, 2, 4
    4                                 print current  0        // Prints 0, 2, 4, 0
    2                                 a = current+2  0
    2                                 current = a    2
    2                                 print current  2        // Prints 0, 2, 4, 0, 2
    4                                 a = current+2  2
    4                                 current = a    4
    4                                 print current  4        // Prints 0, 2, 4, 0, 2, 4
    6                                 a = current+2  4 
    6        a = current+2    4
    6                                 current = a    6
    6        current = a      6
    6        print current                                     // Prints 0, 2, 4, 0, 2, 4, 6
    6                                 print current            // Prints 0, 2, 4, 0, 2, 4, 6, 6
    

    请注意,这不是唯一可能的情况,因为有些操作可以在线程1和线程2之间反转(例如最后两对)

  2. # 2 楼答案

    如果没有比赛条件,答案总是B),因为你增加了相同的变量。但事实并非如此,因为在这段代码中:

     current = a;
     System.out.print(current + ", ");
     a= current + 2;
    

    您设置current=a(它有一些值),使用它进行打印,但在此期间,另一个线程可能修改了a。然后,当您设置a=current+2时,您会覆盖其他线程的更改

    例如,如果步骤是: 最初a=0

    1. 螺纹1电流=a;(T1电流=0)
    2. 螺纹2电流=a;(t2电流也=0)
    3. 线程1打印电流->;0
    4. 螺纹1设置a=电流+2->;a=2
    5. 线程2打印自己的电流,该电流在步骤2中仍为0
    6. 螺纹2设置a=电流+2->;a=2基本上覆盖了另一个线程中发生的步骤4

    所以你也可以得到其他可能的答案,比如:

    0,0,2,4,6,2,4,6

    0,2,4,6,0,2,4,6

    0,2,4,0,2,4,6,6, 等等

    这取决于线程的执行方式,以及我们将current设置为某个值,然后将a设置为current+2之间发生了什么